package com.sykj.seaflow.sys.modual.roleuser.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sykj.seaflow.common.base.bean.PageQuery;
import com.sykj.seaflow.sys.modual.roleuser.entity.SysRoleUser;
import com.sykj.seaflow.sys.modual.roleuser.mapper.SysRoleUserMapper;
import com.sykj.seaflow.sys.modual.role.params.SysRoleGrantUserBatchParam;
import com.sykj.seaflow.sys.modual.role.params.SysRoleGrantUserParam;
import com.sykj.seaflow.sys.modual.role.params.SysRoleRevokeUserParam;
import com.sykj.seaflow.sys.modual.roleuser.params.SysRoleUserIdParam;
import com.sykj.seaflow.sys.modual.roleuser.params.SysRoleUserQuery;
import com.sykj.seaflow.sys.modual.roleuser.service.SysRoleUserService;
import com.sykj.seaflow.sys.modual.user.entity.SysUser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysRoleUserServiceImpl extends ServiceImpl<SysRoleUserMapper, SysRoleUser> implements SysRoleUserService {

    @Transactional
    @Override
    public void batchAdd(List<SysRoleGrantUserParam> grantUserParams) {
        if(ObjectUtil.isNotEmpty(grantUserParams)){
            //过滤掉重复的
            List<SysRoleUser> list = this.list(Wrappers.<SysRoleUser>lambdaQuery().eq(SysRoleUser::getRoleId, grantUserParams.get(0).getRoleId()));

            List<Long> existUserId = list.stream().map(SysRoleUser::getUserId).collect(Collectors.toList());//.toList();
            List<SysRoleGrantUserParam> list1 = grantUserParams.stream().filter(r -> !existUserId.contains(r.getUserId())).collect(Collectors.toList());//.toList();
            List<SysRoleUser> sysRoleUsers = BeanUtil.copyToList(list1, SysRoleUser.class);
            if(ObjectUtil.isNotEmpty(sysRoleUsers)){
                this.saveBatch(sysRoleUsers);
            }
        }
    }
    @Transactional
    @Override
    public void delete(List<SysRoleRevokeUserParam> revokeUserParams) {
        List<Long> roleUserIds = CollectionUtil.map(revokeUserParams, SysRoleRevokeUserParam::getRoleUserId, true);
        if(ObjectUtil.isNotEmpty(roleUserIds)){
            this.removeBatchByIds(roleUserIds);
        }
    }
    @Transactional
    @Override
    public void delByUserIds(List<Long> ids) {
        this.remove(Wrappers.<SysRoleUser>lambdaQuery().in(SysRoleUser::getUserId, ids));
    }
    @Transactional
    @Override
    public void delByRoleIds(List<Long> ids) {
        this.remove(Wrappers.<SysRoleUser>lambdaQuery().in(SysRoleUser::getRoleId, ids));
    }

    @Override
    public List<SysRoleUser> listByRoleId(Long id) {
        return this.list(Wrappers.<SysRoleUser>lambdaQuery().eq(SysRoleUser::getRoleId, id));
    }

    @Transactional
    @Override
    public void batchGrant(SysRoleGrantUserBatchParam grantUserParams) {
        //过于豪放
        Long roleId = grantUserParams.getRoleId();
        this.delByRoleIds(Arrays.asList(roleId));
        List<Long> userIds = grantUserParams.getUserIds();
        if(ObjectUtil.isNotEmpty(userIds)){
            List<SysRoleUser> sysRoleUsers = userIds.stream().map(r -> {
                SysRoleUser sysRoleUser = new SysRoleUser();
                sysRoleUser.setRoleId(roleId);
                sysRoleUser.setUserId(r);
                return sysRoleUser;
            }).collect(Collectors.toList());//.toList();
            this.saveBatch(sysRoleUsers);
        }

    }
    @Transactional
    @Override
    public List<SysUser> grantedGpage(SysRoleUserQuery sysRoleUserQuery, PageQuery pageQuery) {
        QueryWrapper<SysUser> query = Wrappers.query();
        if(ObjectUtil.isNotEmpty(sysRoleUserQuery.getRoleId())){
            query.eq("ru.role_id", sysRoleUserQuery.getRoleId());
        }
        buildGrantQuery(sysRoleUserQuery, query);
        return this.getBaseMapper().page(pageQuery.getPage(), query);
    }

    @Override
    public List<SysUser> canGrantPage(SysRoleUserQuery sysRoleUserQuery, PageQuery pageQuery) {
        QueryWrapper<SysUser> query = Wrappers.query();
        if(ObjectUtil.isNotEmpty(sysRoleUserQuery.getRoleId())){
            query.nested(wrap ->
                        //左连接查询 必须两个都设置，  eq查询会过滤为null的数据， 再 or 为null的数据 即可
                    // 写法 替换 子查询 not in 这种方式
                    wrap.ne("ru.role_id", sysRoleUserQuery.getRoleId())
                            .or().isNull("ru.role_id"));
        }
        buildGrantQuery(sysRoleUserQuery, query);
        return this.getBaseMapper().canGrantPage(pageQuery.getPage(), query);
    }

    @Override
    public boolean revoke(List<SysRoleUserIdParam> roleUserIdParams) {
        List<Long> ids = CollectionUtil.map(roleUserIdParams, SysRoleUserIdParam::getId, true);
        return removeBatchByIds(ids);
    }

    @Override
    public List<Long> listbyRoleIds(List<String> roleIds) {
        LambdaQueryWrapper<SysRoleUser> lambdaQueryWrapper = Wrappers.<SysRoleUser>lambdaQuery().in(SysRoleUser::getRoleId, roleIds);
        List<SysRoleUser> list = this.list(lambdaQueryWrapper);
        return list.stream().map(SysRoleUser::getUserId).collect(Collectors.toList());//.toList();
    }

    @Override
    public List<SysRoleUser> listByUserId(Long userId) {
        LambdaQueryWrapper<SysRoleUser> lambdaQueryWrapper = Wrappers.<SysRoleUser>lambdaQuery().eq(SysRoleUser::getUserId, userId);
        return this.list(lambdaQueryWrapper);
    }

    private void buildGrantQuery(SysRoleUserQuery sysRoleUserQuery, QueryWrapper<SysUser> query) {
        if(ObjectUtil.isNotEmpty(sysRoleUserQuery.getKeywords())){
            query.and(r-> r.like("u.username", sysRoleUserQuery.getKeywords()).or().like("u.nick", sysRoleUserQuery.getKeywords()));
        }
        if(ObjectUtil.isNotEmpty(sysRoleUserQuery.getPhone())){
            query.like("u.phone", sysRoleUserQuery.getPhone());
        }
    }
}
